import { Subscription } from 'rxjs';
import { ReactiveProperty } from './ReactiveProperty';
import { nullifySubscription } from '../utils';

export class LifeCycleReactive {

    binded = ReactiveProperty.Create(false);

    /**
     * 
     * @returns 返回一个Subscription，或者一个同步返回Subscription类型的函数
     */
    useObserves?(): (Subscription | (() => Subscription) | null)[] { return null; }

    _mainSubscription?: Subscription = null;
    getMainSubscription() { return this._mainSubscription; }

    // ExtraManagedSubscriptions
    _extraManagedSubscriptions?: Record<string, Subscription> = {};
    getExtraManagedSubscriptions() { return this._extraManagedSubscriptions; }
    extraManagedUnsubscribe?() {
        for (let key in this._extraManagedSubscriptions) {
            let element = this._extraManagedSubscriptions[key];
            !element.closed && element.unsubscribe()
            delete this._extraManagedSubscriptions[key];
        }
    }
    resetSubscriptions(key: string, genSubscription: () => Subscription) {
        nullifySubscription.call(this._extraManagedSubscriptions, key);
        this._extraManagedSubscriptions[key] = genSubscription();
    }

    bind() {
        this._mainSubscription = this.binded.subscribePairWise(pair => {
            if (!pair[0] && pair[1]) {
                this.manualBind(this.useObserves());
            } else if (pair[0] && !pair[1]) {
                this._mainSubscription.unsubscribe();
                this.extraManagedUnsubscribe();
            } else {
                console.log('pair', pair);
            }
        });
        this.binded.value = true;
    }

    unbind() {
        this.binded.value = false;
    }

    manualBind?(list: (Subscription | (() => Subscription) | null)[]) {
        list?.forEach(element => {
            if (!element) return;
            if (typeof element == 'function') {
                this._mainSubscription.add(element());
            } else {
                this._mainSubscription.add(element);
            }
        });
    }

}